#include <libtcod/libtcod.hpp>

#include "Log.hpp"
#include "Material.hpp"

std::vector<MaterialData> Material::data;

class MaterialDataParser : public ITCODParserListener
{
	std::string CurrentStruct;

	bool parserNewStruct(TCODParser* parser, const TCODParserStruct* str, const char* name)
	{
		CurrentStruct = str->getName();
		
		if (CurrentStruct.compare("material") == 0)
		{
			MaterialData mat;
			mat.Name = name;
			Material::data.push_back(mat);
		}
		else if (CurrentStruct.compare("burnable") == 0)
		{
			Material::data.back().Burnable.Found = true;
		}

		return true;
	}
	
	bool parserFlag(TCODParser* parser, const char* name)
	{
		return true;
	}

	bool parserProperty(TCODParser* parser, const char* name, TCOD_value_type_t type, TCOD_value_t value)
	{
		std::string sname = name;

		if (CurrentStruct.compare("material") == 0)
		{
		}
		else if (CurrentStruct.compare("burnable") == 0)
		{
			if (sname.compare("burnTimer") == 0)
				Material::data.back().Burnable.BurnTimer = value.i;
			else if (sname.compare("flammability") == 0)
				Material::data.back().Burnable.Flammability = value.i;
			else if (sname.compare("spreads") == 0)
				Material::data.back().Burnable.Spreads = value.i;
		}
		return true;
	}

	bool parserEndStruct(TCODParser* parser, const TCODParserStruct* str, const char* name)
	{
		return true;
	}

	void error(const char* msg)
	{
		std::string message = "ERROR: ";
		message += msg;
		Log::write(message);
	}

public:
	MaterialDataParser() : ITCODParserListener() {}
};

int Material::getByName(std::string name)
{
	for (unsigned int i = 0; i < data.size(); ++i)
		if (name.compare(data[i].Name) == 0)
			return i;
	return 0;
}

void Material::load()
{
	Log::write("Loading materials...");
	TCODParser parser;
	TCODParserStruct* base = parser.newStructure("material");

	TCODParserStruct* burnable = parser.newStructure("burnable");
	burnable->addProperty("burnTimer", TCOD_TYPE_INT, true);
	burnable->addProperty("flammability", TCOD_TYPE_INT, true);
	burnable->addProperty("spreads", TCOD_TYPE_INT, true);
	base->addStructure(burnable);
	
	MaterialDataParser listener;
	parser.run("data/materials", &listener);
	Log::write("Materials loaded.");
}
